package com.kun.companion.core.http.request;

import com.fasterxml.jackson.annotation.JsonProperty;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;

/**
 * DeepSeek API 请求参数实体类
 * <p>完整API文档参考：https://platform.deepseek.com/api-docs
 *
 * @author gzc
 * @since 2025/3/1
 **/
public class DeepSeekRequest implements Serializable {

    /**
     * 指定使用的模型名称
     * <p>示例："deepseek-chat" 或 "deepseek-coder"
     * <p>必填字段，需从可用模型列表中选择
     */
    private String model;

    /**
     * 对话消息列表（按时间顺序排列）
     * <p>每条消息需包含角色（system/user/assistant）和内容
     * <p>至少需要1条消息，最大支持10条历史消息
     */
    private List<Message> messages;

    /**
     * 频率惩罚系数（-2.0 ~ 2.0）
     * <p>正值降低重复内容生成概率，建议值：0.1-1.0
     * <p>默认值：0
     */
    @JsonProperty("frequency_penalty")
    private double frequencyPenalty;

    /**
     * 生成结果的最大token数
     * <p>需结合模型上下文长度限制设置（如：模型支持16k则最大设为16384）
     * <p>默认值：模型最大值
     */
    @JsonProperty("max_tokens")
    private int maxTokens;

    /**
     * 存在惩罚系数（-2.0 ~ 2.0）
     * <p>正值增加模型讨论新话题的可能性
     * <p>默认值：0
     */
    @JsonProperty("presence_penalty")
    private double presencePenalty;

    /**
     * 响应格式控制
     * <p>可指定返回格式为JSON对象（"type": "json_object"）
     * <p>默认返回文本格式
     */
    @JsonProperty("response_format")
    private ResponseFormat responseFormat;

    /**
     * 停止生成标记（最多4个）
     * <p>支持字符串或字符串数组，当生成内容包含这些标记时停止
     * <p>示例：["\n", "。"]
     * <p>默认值：null
     */
    private Object stop;

    /**
     * 是否启用流式响应
     * <p>true：启用流式传输（需特殊处理响应）
     * <p>false：普通响应（默认）
     */
    private boolean stream;

    /**
     * 流式传输选项
     * <p>仅在stream=true时生效，可设置include_usage等参数
     * <p>默认值：null
     */
    @JsonProperty("stream_options")
    private Object streamOptions;

    /**
     * 温度系数（0.0 ~ 2.0）
     * <p>控制生成随机性：值越高结果越随机
     * <p>建议值：0.7（创意场景）或 0.2（确定性场景）
     * <p>默认值：1.0
     */
    private double temperature;

    /**
     * 核心采样阈值（0.0 ~ 1.0）
     * <p>仅从概率累加达到该值的token中采样
     * <p>建议与temperature二选一使用
     * <p>默认值：1.0
     */
    @JsonProperty("top_p")
    private double topP;

    /**
     * 可用工具列表（函数调用）
     * <p>需按照OpenAI工具格式定义
     * <p>默认值：null
     */
    private Object tools;

    /**
     * 工具调用策略
     * <p>"auto"：自动选择工具
     * <p>"none"：不调用工具（默认）
     * <p>特定工具名称：强制使用指定工具
     */
    @JsonProperty("tool_choice")
    private String toolChoice;

    /**
     * 是否返回对数概率
     * <p>true：返回每个token的对数概率
     * <p>false：不返回（默认）
     */
    private boolean logprobs;

    /**
     * 返回最可能的token数量（1~5）
     * <p>需logprobs=true时生效
     * <p>默认值：null（返回所有可能）
     */
    @JsonProperty("top_logprobs")
    private Object topLogprobs;


    public static DeepSeekRequest defaultRequest(String userMessage) {
        DeepSeekRequest deepSeekRequest = new DeepSeekRequest();
        deepSeekRequest.setModel("deepseek-chat");
        deepSeekRequest.setMessages(Arrays.asList(
                new Message("system", "You are a helpful assistant"),
                new Message("user", userMessage)
        ));
        deepSeekRequest.setFrequencyPenalty(0);
        deepSeekRequest.setMaxTokens(2048);
        deepSeekRequest.setPresencePenalty(0);
        deepSeekRequest.setResponseFormat(new ResponseFormat("text"));
        deepSeekRequest.setStream(false);
        deepSeekRequest.setTemperature(1);
        deepSeekRequest.setTopP(1);
        deepSeekRequest.setLogprobs(false);
        return deepSeekRequest;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public List<Message> getMessages() {
        return messages;
    }

    public void setMessages(List<Message> messages) {
        this.messages = messages;
    }

    public double getFrequencyPenalty() {
        return frequencyPenalty;
    }

    public void setFrequencyPenalty(double frequencyPenalty) {
        this.frequencyPenalty = frequencyPenalty;
    }

    public int getMaxTokens() {
        return maxTokens;
    }

    public void setMaxTokens(int maxTokens) {
        this.maxTokens = maxTokens;
    }

    public double getPresencePenalty() {
        return presencePenalty;
    }

    public void setPresencePenalty(double presencePenalty) {
        this.presencePenalty = presencePenalty;
    }

    public ResponseFormat getResponseFormat() {
        return responseFormat;
    }

    public void setResponseFormat(ResponseFormat responseFormat) {
        this.responseFormat = responseFormat;
    }

    public Object getStop() {
        return stop;
    }

    public void setStop(Object stop) {
        this.stop = stop;
    }

    public boolean isStream() {
        return stream;
    }

    public void setStream(boolean stream) {
        this.stream = stream;
    }

    public Object getStreamOptions() {
        return streamOptions;
    }

    public void setStreamOptions(Object streamOptions) {
        this.streamOptions = streamOptions;
    }

    public double getTemperature() {
        return temperature;
    }

    public void setTemperature(double temperature) {
        this.temperature = temperature;
    }

    public double getTopP() {
        return topP;
    }

    public void setTopP(double topP) {
        this.topP = topP;
    }

    public Object getTools() {
        return tools;
    }

    public void setTools(Object tools) {
        this.tools = tools;
    }

    public String getToolChoice() {
        return toolChoice;
    }

    public void setToolChoice(String toolChoice) {
        this.toolChoice = toolChoice;
    }

    public boolean isLogprobs() {
        return logprobs;
    }

    public void setLogprobs(boolean logprobs) {
        this.logprobs = logprobs;
    }

    public Object getTopLogprobs() {
        return topLogprobs;
    }

    public void setTopLogprobs(Object topLogprobs) {
        this.topLogprobs = topLogprobs;
    }

    public static class Message {
        private String role;
        private String content;

        public Message(String role, String content) {
            this.role = role;
            this.content = content;
        }

        public String getRole() {
            return role;
        }

        public void setRole(String role) {
            this.role = role;
        }

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }
    }

    public static class ResponseFormat {
        private String type;

        public ResponseFormat(String type) {
            this.type = type;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }
    }
}
